package ferror

import (
	"fmt"
	"github.com/pkg/errors"
	"io"
)

// 应用错误
type AppError struct {
	Msg      string `json:"msg"`
	Code     string `json:"code"`
	SubError error  `json:"-"`
}

func (a AppError) Error() string {
	if a.SubError != nil {
		appError, ok := a.SubError.(AppError)
		if ok {
			return appError.Error()
		}
	}
	if a.Code != "" {
		return a.Code + ":" + a.Msg
	}
	return a.Msg
}

func (w AppError) Format(s fmt.State, verb rune) {
	switch verb {
	case 'v':
		if s.Flag('+') {
			io.WriteString(s, w.Code+":"+w.Msg+"\n")

			fmt.Fprintf(s, "%+v\n", w.SubError)
			return
		}
		fallthrough
	case 's', 'q':
		io.WriteString(s, w.Error())
	}
}

func Wrap(msg string, subError error) error {

	return errors.Wrap(subError, msg)
}

func WrapWithCode(msg string, code string, subError error) error {
	return AppError{
		Msg:      msg,
		Code:     code,
		SubError: subError,
	}
}

func New(msg string) error {
	return errors.New(msg)
}

func NewWithCode(msg, code string) error {
	return errors.New(code + ":" + msg)
}
